/**
 ******************************************************************************
 * @file    C8624.c
 * @author  Wu Zhe Wei
 * @version V1.0
 * @date
 * @brief   Command and communication driver level with C8624.
 *          Functional configuration and low level display function.
 ******************************************************************************
 /**
  ******************************************************************************
  * @file    C8625.c
  * @author  Wu Zhe Wei
  * @version V1.0
  * @date
  * @brief   Command and communication driver level with C8625.
  *          Functional configuration and low level display function.

         SEG1 A            SEG2 B             SEG3  C           SEG4 D              SEG5  E            SEG6  F            SEG7   G           SEG8  H            SEG9  J            SEG10 K            SEG11   L         SEG12 M             SEG13 N             SEG14 P              SEG15 Q
GRID1 C8625_DisplayBuf[0]   C8625_DisplayBuf[1]   C8625_DisplayBuf[2]   C8625_DisplayBuf[3]   C8625_DisplayBuf[4]   C8625_DisplayBuf[5]   C8625_DisplayBuf[6]   C8625_DisplayBuf[7]   C8625_DisplayBuf[8]   C8625_DisplayBuf[9]   C8625_DisplayBuf[10]  C8625_DisplayBuf[11]  C8625_DisplayBuf[12]  C8625_DisplayBuf[13]  C8625_DisplayBuf[14]
GRID2 C8625_DisplayBuf[15]  C8625_DisplayBuf[16]  C8625_DisplayBuf[17]  C8625_DisplayBuf[18]  C8625_DisplayBuf[19]  C8625_DisplayBuf[20]  C8625_DisplayBuf[21]  C8625_DisplayBuf[22]  C8625_DisplayBuf[23]  C8625_DisplayBuf[24]  C8625_DisplayBuf[25]  C8625_DisplayBuf[26]  C8625_DisplayBuf[27]  C8625_DisplayBuf[28]  C8625_DisplayBuf[29]
GRID3 C8625_DisplayBuf[30]  C8625_DisplayBuf[31]  C8625_DisplayBuf[32]  C8625_DisplayBuf[33]  C8625_DisplayBuf[34]  C8625_DisplayBuf[35]  C8625_DisplayBuf[36]  C8625_DisplayBuf[37]  C8625_DisplayBuf[38]  C8625_DisplayBuf[39]  C8625_DisplayBuf[40]  C8625_DisplayBuf[41]  C8625_DisplayBuf[42]  C8625_DisplayBuf[43]  C8625_DisplayBuf[44]
GRID4 C8625_DisplayBuf[45]  C8625_DisplayBuf[46]  C8625_DisplayBuf[47]  C8625_DisplayBuf[48]  C8625_DisplayBuf[49]  C8625_DisplayBuf[50]  C8625_DisplayBuf[51]  C8625_DisplayBuf[52]  C8625_DisplayBuf[53]  C8625_DisplayBuf[54]  C8625_DisplayBuf[55]  C8625_DisplayBuf[56]  C8625_DisplayBuf[57]  C8625_DisplayBuf[58]  C8625_DisplayBuf[59]
GRID5 C8625_DisplayBuf[60]  C8625_DisplayBuf[61]  C8625_DisplayBuf[62]  C8625_DisplayBuf[63]  C8625_DisplayBuf[64]  C8625_DisplayBuf[65]  C8625_DisplayBuf[66]  C8625_DisplayBuf[67]  C8625_DisplayBuf[68]  C8625_DisplayBuf[69]  C8625_DisplayBuf[70]  C8625_DisplayBuf[71]  C8625_DisplayBuf[72]  C8625_DisplayBuf[73]  C8625_DisplayBuf[74]
GRID6 C8625_DisplayBuf[75]  C8625_DisplayBuf[76]  C8625_DisplayBuf[77]  C8625_DisplayBuf[78]  C8625_DisplayBuf[79]  C8625_DisplayBuf[80]  C8625_DisplayBuf[81]  C8625_DisplayBuf[82]  C8625_DisplayBuf[83]  C8625_DisplayBuf[84]  C8625_DisplayBuf[85]  C8625_DisplayBuf[86]  C8625_DisplayBuf[87]  C8625_DisplayBuf[88]  C8625_DisplayBuf[89]
GRID7 C8625_DisplayBuf[90]  C8625_DisplayBuf[91]  C8625_DisplayBuf[92]  C8625_DisplayBuf[93]  C8625_DisplayBuf[94]  C8625_DisplayBuf[95]  C8625_DisplayBuf[96]  C8625_DisplayBuf[97]  C8625_DisplayBuf[98]  C8625_DisplayBuf[99]  C8625_DisplayBuf[100] C8625_DisplayBuf[101] C8625_DisplayBuf[102] C8625_DisplayBuf[103] C8625_DisplayBuf[104]
GRID8 C8625_DisplayBuf[105] C8625_DisplayBuf[106] C8625_DisplayBuf[107] C8625_DisplayBuf[108] C8625_DisplayBuf[109] C8625_DisplayBuf[110] C8625_DisplayBuf[111] C8625_DisplayBuf[112] C8625_DisplayBuf[113] C8625_DisplayBuf[114] C8625_DisplayBuf[115] C8625_DisplayBuf[116] C8625_DisplayBuf[117] C8625_DisplayBuf[118] C8625_DisplayBuf[119]

  *********************************************************************************************************************************************************************************************************************************************/

#include "./Common_Include.h"
#ifdef EN_I2C_C8625

/*
 * @brief  public variable define
 * @note
 */
Ram c8625_ty_cmd_config_t c8625_tCmdConfig;
Ram c8625_ty_cmd_setting_t c8625_tCmdSetting;
Ram unsigned char C8625_DisplayBuf[C8625_BUF_SIZE];

CONST unsigned char BreathGamma[] = {
    0, 1, 2, 3, 4, 5, 6, 7,
    8, 10, 12, 14, 16, 18, 20, 22,
    24, 26, 29, 32, 35, 38, 41, 44,
    47, 50, 53, 57, 61, 65, 69, 73,
    77, 81, 85, 89, 94, 99, 104, 109,
    114, 119, 124, 129, 134, 140, 146, 152,
    158, 164, 170, 176, 182, 188, 195, 202,
    209, 216, 223, 230, 237, 244, 251, 255,
    255, 251, 244, 237, 230, 223, 216, 209,
    202, 195, 188, 182, 176, 170, 164, 158,
    152, 146, 140, 134, 129, 124, 119, 114,
    109, 104, 99, 94, 89, 85, 81, 77,
    73, 69, 65, 61, 57, 53, 50, 47,
    44, 41, 38, 35, 32, 29, 26, 24,
    22, 20, 18, 16, 14, 12, 10, 8,
    7, 6, 5, 4, 3, 2, 1, 0};

/**
 * @function C8625_SetCurrentCommand()
 * -------------------------------
 * @brief    Configure the current setting command.
 * @param    None
 * @note     None
 */
static void Dev_C8625_SetCurrentCommand()
{
  c8625_tCmdSetting.Current = c8625_tCmdConfig.emCurrentGain; //  C8625 寄存器1  bit6  bit7 默认0
}

/**
 * @function Dev_C8625_SetModeCommand()
 * ----------------------------
 * @brief    Configure the mode setting command.
 * @param    None
 * @note     None
 */
static void Dev_C8625_SetModeCommand()
{
  c8625_tCmdSetting.Mode = (c8625_tCmdConfig.emClockMode << 7) + (c8625_tCmdConfig.emComScan << 2) + (c8625_tCmdConfig.emWorkMode << 1) + c8625_tCmdConfig.emDataUpdata;
}

/**
 * @function Dev_C8625_SetDisplayCommand()
 * -------------------------------
 * @brief    Configure the display setting command.
 * @param    None
 * @note     None
 */
static void Dev_C8625_SetDisplayCommand()
{
  c8625_tCmdSetting.Display = (c8625_tCmdConfig.emOverT125Protect << 7) + (c8625_tCmdConfig.emPwmClock << 4) + (c8625_tCmdConfig.emDisplay << 3) + (c8625_tCmdConfig.emGhostReduction << 2) + c8625_tCmdConfig.emRowBreakTime;
}

/**
 * @function Dev_C8625_SetControlCommand()
 * -------------------------------
 * @brief    Configure the control setting command.
 * @param    None
 * @note     None
 */
static void Dev_C8625_SetControlCommand()
{
  c8625_tCmdSetting.Control = (c8625_tCmdConfig.emSleepFunction << 6) + (c8625_tCmdConfig.emAutoSleepFunction << 5) + (c8625_tCmdConfig.emGlobalReset << 4) + (c8625_tCmdConfig.emSoftReset << 3) + (c8625_tCmdConfig.emOverT150Protect << 1) + c8625_tCmdConfig.emPowerDownReset;
}

/**
 * @function Dev_C8625_SendCommandPackage()
 * --------------------------------
 * @brief    Sending command package to led driver.
 * @param    cmdType - command type
 * @note     None
 */
static void Dev_C8625_SendCommandPackage(c8625_em_cmd_type_t cmdType)
{
  unsigned char checkSum = 0;
  unsigned char command;

  Drv_I2c_Send_Byte_Fast(e_INDEX_I2C_C8625, 0x5A);
  Drv_I2c_Send_Byte_Fast(e_INDEX_I2C_C8625, 0xFF);
  c8625_tCmdConfig.emCmdType = cmdType;
  command = (c8625_tCmdConfig.emcmdBroadcastEnable << 6) + (c8625_tCmdConfig.emCsAddress << 4) + c8625_tCmdConfig.emCmdType;
  Drv_I2c_Send_Byte_Fast(e_INDEX_I2C_C8625, command);
  checkSum = 0x5A + 0xFF + command;
  Drv_I2c_Send_Byte_Fast(e_INDEX_I2C_C8625, checkSum);
}

/**
 * @function Dev_C8625_SendSetPackage()
 * ----------------------------
 * @brief    Sending set package to led driver.
 * @param    None
 * @note     None
 */
static void Dev_C8625_SendSetPackage()
{
  unsigned char checkSum = 0;

  Drv_I2c_Send_Byte_Fast(e_INDEX_I2C_C8625, c8625_tCmdSetting.Current);
  Drv_I2c_Send_Byte_Fast(e_INDEX_I2C_C8625, c8625_tCmdSetting.Mode);
  Drv_I2c_Send_Byte_Fast(e_INDEX_I2C_C8625, c8625_tCmdSetting.Display);
  Drv_I2c_Send_Byte_Fast(e_INDEX_I2C_C8625, c8625_tCmdSetting.Control);
  checkSum = c8625_tCmdSetting.Current + c8625_tCmdSetting.Mode + c8625_tCmdSetting.Display + c8625_tCmdSetting.Control;
  Drv_I2c_Send_Byte_Fast(e_INDEX_I2C_C8625, checkSum);
}

/**
 * @function Dev_C8625_SendDataFrame()
 * ---------------------------
 * @brief    Sending data frame to led driver.
 * @param    *pDataBuf - point to data buffer
 * @note     None
 */
static void Dev_C8625_SendDataFrame(unsigned char *pDataBuf)
{
  unsigned char checkSum = 0;
  unsigned short i, dataLength = 0;

  dataLength = C8625_SEG_NUM * (c8625_tCmdConfig.emComScan + 1);

  Dev_C8625_SendCommandPackage(C8625_CmdCommand);
  Dev_C8625_SendSetPackage();
  Dev_C8625_SendCommandPackage(C8625_CmdData);

  checkSum = 0;
  for (i = 0; i < dataLength; i++)
  {
    Drv_I2c_Send_Byte_Fast(e_INDEX_I2C_C8625, *(pDataBuf + i));
    checkSum += *(pDataBuf + i);
  }
  Drv_I2c_Send_Byte_Fast(e_INDEX_I2C_C8625, checkSum);
}

/**
 * @function Dev_C8625_ConfigCommand()
 * ---------------------------
 * @brief    Config the command paramaters.
 * @param    None
 * @note     None
 */
void Dev_C8625_ConfigCommand()
{
  c8625_tCmdConfig.emcmdBroadcastEnable = C8625_CSMode;          // CSmode
  c8625_tCmdConfig.emCsAddress = C8625_CsAddress0;               // chip address
  c8625_tCmdConfig.emCmdType = C8625_CmdCommand;                 // command type
  c8625_tCmdConfig.emCurrentGain = C8625_mA_30;                  // current value
  c8625_tCmdConfig.emClockMode = C8625_InternalClock;            // internal clock mode
  c8625_tCmdConfig.emComScan = C8625_Com8;                       // number of com ports in use
  c8625_tCmdConfig.emWorkMode = C8625_NormalMode;                // work mode
  c8625_tCmdConfig.emDataUpdata = C8625_AutomaticUpdate;         // data update mode, recommend automatic update
  c8625_tCmdConfig.emOverT125Protect = C8625_Otp125Enable;       // temperature protection1 -125?
  c8625_tCmdConfig.emPwmClock = C8625_Clock1M;                   // pwm clock frequency
  c8625_tCmdConfig.emDisplay = C8625_DisplayEnable;              // diaplay enable
  c8625_tCmdConfig.emGhostReduction = C8625_Strong;              // ghosting
  c8625_tCmdConfig.emRowBreakTime = C8625_PwmCycle8;             // scanning interval
  c8625_tCmdConfig.emSleepFunction = C8625_SleepDisable;         // sleep enable
  c8625_tCmdConfig.emAutoSleepFunction = C8625_AutoSleepDisable; // auto sleep disable
  c8625_tCmdConfig.emGlobalReset = C8625_GlobalDisable;          // global reset (clear RAM)
  c8625_tCmdConfig.emSoftReset = C8625_SoftDisable;              // soft reset (refresh display)
  c8625_tCmdConfig.emOverT150Protect = C8625_Otp150Enable;       // temperature protection1 -150?
  c8625_tCmdConfig.emPowerDownReset = C8625_PowerEnable;         // power-off reset
}

/**
 * @function Dev_C8625_ReconfigCommand()
 * -----------------------------
 * @brief    Reconfig the command paramaters.
 * @param    None
 * @note     None
 */
void Dev_C8625_ReconfigCommand()
{
  c8625_tCmdConfig.emcmdBroadcastEnable = C8625_CSMode;
  c8625_tCmdConfig.emCsAddress = C8625_CsAddress0;
  c8625_tCmdConfig.emCmdType = C8625_CmdCommand;
  c8625_tCmdConfig.emCurrentGain = C8625_mA_30;
  c8625_tCmdConfig.emClockMode = C8625_InternalClock;
  c8625_tCmdConfig.emComScan = C8625_Com8;
  c8625_tCmdConfig.emWorkMode = C8625_NormalMode;
  c8625_tCmdConfig.emDataUpdata = C8625_AutomaticUpdate;
  c8625_tCmdConfig.emOverT125Protect = C8625_Otp125Enable;
  c8625_tCmdConfig.emPwmClock = C8625_Clock8M;
  c8625_tCmdConfig.emDisplay = C8625_DisplayEnable;
  c8625_tCmdConfig.emGhostReduction = C8625_Strong;
  c8625_tCmdConfig.emRowBreakTime = C8625_PwmCycle8;
  c8625_tCmdConfig.emSleepFunction = C8625_SleepDisable;
  c8625_tCmdConfig.emAutoSleepFunction = C8625_AutoSleepDisable;
  c8625_tCmdConfig.emGlobalReset = C8625_GlobalDisable;
  c8625_tCmdConfig.emSoftReset = C8625_SoftDisable;
  c8625_tCmdConfig.emOverT150Protect = C8625_Otp150Enable;
  c8625_tCmdConfig.emPowerDownReset = C8625_PowerEnable;

  Dev_C8625_SetCurrentCommand();
  Dev_C8625_SetModeCommand();
  Dev_C8625_SetDisplayCommand();
  Dev_C8625_SetControlCommand();
}

/**
 * @function Dev_C8625_Init()
 * ------------------
 * @brief    Initlize all led drivers.
 * @param    None
 * @note     None
 */
void Dev_C8625_Init(void)
{

  Dev_C8625_ConfigCommand();
  Dev_C8625_SetCurrentCommand();
  Dev_C8625_SetModeCommand();
  Dev_C8625_SetDisplayCommand();
  Dev_C8625_SetControlCommand();
}

/**
 * @function Dev_C8625_DisplayClearBuf()
 * -----------------------------
 * @brief    Clear all display buffer.
 * @param    None
 * @note     None
 */
void Dev_C8625_DisplayClearBuf(void)
{
  unsigned short i;
  unsigned short dataLength = 0;

  dataLength = C8625_SEG_NUM * (c8625_tCmdConfig.emComScan + 1);

  for (i = 0; i < dataLength; i++)
    C8625_DisplayBuf[i] = 0;
}

/**
 * @function Dev_C8625_DisplayAll()
 * ------------------------
 * @brief    Display all led with special luminance.
 * @param    lumi - brightness value (0x00 ~ 0xFF)
 * @note     None
 */
void Dev_C8625_DisplayAll(unsigned char lumi)
{
  unsigned short i;
  unsigned short dataLength = 0;

  dataLength = C8625_SEG_NUM * (c8625_tCmdConfig.emComScan + 1);

  for (i = 0; i < dataLength; i++)
    C8625_DisplayBuf[i] = lumi;

  Dev_C8625_SendDataFrame(C8625_DisplayBuf);
  Dev_C8625_SendCommandPackage(C8625_CmdDataUpdate);
  Drv_I2c_Send_NAck(e_INDEX_I2C_C8625);
}

/**
 * @function Dev_C8625_SendAddressData()
 * ---------------------------
 * @brief    Sending Addressdata to led driver.
 * @param    DataAddr  - Data Address
 *           Data        Display Data
 * @note     None
 */
void Dev_C8625_SendAddressData(unsigned char DataAddr, unsigned char Data)
{
  unsigned char checkSum = 0;
  Dev_C8625_SendCommandPackage(C8625_CmdCommand);
  Dev_C8625_SendSetPackage();
  Dev_C8625_SendCommandPackage(C8625_CmdAdressData);
  checkSum = 0;
  Drv_I2c_Send_Byte_Fast(e_INDEX_I2C_C8625, DataAddr);
  Drv_I2c_Send_Byte_Fast(e_INDEX_I2C_C8625, Data);
  Drv_I2c_Send_Byte_Fast(e_INDEX_I2C_C8625, 0xff);
  checkSum = (DataAddr + Data + 0xff);
  Drv_I2c_Send_Byte_Fast(e_INDEX_I2C_C8625, checkSum);
  Dev_C8625_SendCommandPackage(C8625_CmdDataUpdate);
  Drv_I2c_Send_NAck(e_INDEX_I2C_C8625);
}

/**
 * @function Dev_C8625_DisplayBufAutomatic()
 * ---------------------------------
 * @brief    Write luminance of the display buffer to led
 *           driver, automatic update the display.
 * @param    None
 * @note     None
 */
void Dev_C8625_DisplayBufAutomatic(void)
{
  Dev_C8625_SendDataFrame(C8625_DisplayBuf);
  Dev_C8625_SendCommandPackage(C8625_CmdDataUpdate);
  Drv_I2c_Send_NAck(e_INDEX_I2C_C8625);
}

/**
 * @function Dev_C8625_DisplayIntoSleep()
 * ------------------------------
 * @brief    Led driver into sleep mode.
 * @param    None
 * @note     None
 */
void Dev_C8625_DisplayIntoSleep(void)
{
  Dev_C8625_SendCommandPackage(C8625_CmdCommand);
  c8625_tCmdConfig.emSleepFunction = C8625_SleepEnable;
  Dev_C8625_SetControlCommand();
  Dev_C8625_SendSetPackage();
  Dev_C8625_SendCommandPackage(C8625_CmdSleep);
  Drv_I2c_Send_NAck(e_INDEX_I2C_C8625);
}

/**
 * @function Dev_C8625_DisplayWakeUp()
 * ---------------------------
 * @brief    Led driver wakeup from sleep mode.
 * @param    None
 * @note     None
 */
void Dev_C8625_DisplayWakeUp(void)
{
  Dev_C8625_SendCommandPackage(C8625_CmdWakeUp);
  Dev_C8625_SendCommandPackage(C8625_CmdCommand);
  c8625_tCmdConfig.emSleepFunction = C8625_SleepDisable;
  Dev_C8625_SetControlCommand();
  Dev_C8625_SendSetPackage();
  Drv_I2c_Send_NAck(e_INDEX_I2C_C8625);
}

/**
 * @function Dev_C8625_DisplayBreathBuf()
 * ------------------------------
 * @brief    Show breathing effect in display buffer.
 * @param    BREATH_TIME - time to run a single step
 * @retval   sbreathBuf  - breathing display buf
 */
unsigned char Dev_C8625_DisplayBreathBuf(void)
{
  static unsigned char sbreathCount = 0;
  static unsigned char sbreathBuf = 0;
  static unsigned char sbreathFlag = 0;

  if (!sbreathFlag)
  {
    if ((sbreathCount + 1) < sizeof(BreathGamma))
      sbreathCount++;
    else
      sbreathFlag = 1;
  }
  else
  {
    if (sbreathCount > 0)
      sbreathCount--;
    else
      sbreathFlag = 0;
  }
  sbreathBuf = BreathGamma[sbreathCount];

  return (sbreathBuf);
}

/**
 * @function Dev_C8625_DisplayMarqueeBuf()
 * -------------------------------
 * @brief    Show marquee effect in display buffer.
 * @param    MARQUEE_TIME - time to run a single step
 * @retval   smarqueeBuf  - address of marquee display buf
 */
unsigned char *Dev_C8625_DisplayMarqueeBuf(void)
{
  unsigned char i, tmp;
  static Ram unsigned char smarqueeBuf[C8625_MARQUEE_NUM] = {8, 16, 32, 64, 128, 255};

  // if (MARQUEE_TIME)
  {
    for (i = (C8625_MARQUEE_NUM - 1); i > 0; i--)
    {
      if (i == (C8625_MARQUEE_NUM - 1))
        tmp = smarqueeBuf[i];
      smarqueeBuf[i] = smarqueeBuf[i - 1];

      if (i == 1)
        smarqueeBuf[i - 1] = tmp;
    }
  }

  return (smarqueeBuf);
}
void Dev_C8625_Scan(void)
{
  static unsigned char tick = 0;
  if (Drv_Autoload_Ntick_u8(&tick, 20ul)) // 40ms处理一次   DXY
  {
    //  Dev_C8625_DisplayClearBuf();
    //  Dev_C8625_DisplayAll(0xFF);         //全亮
    Dev_C8625_DisplayBufAutomatic();
  }
}
#endif
/* [] END OF FILE */
